From 7efba1c2000a2ee409ec1e8d51d06db7ddc93e24 Mon Sep 17 00:00:00 2001 From: oliskoli Date: Tue, 13 Jun 2006 22:02:01 +0000 Subject: [PATCH] BUG fix: wrong format for coordinates (abs(lat or lon) >= 100). Add new option 'date' to specify the used date format for read and write ops. --- pathaway.c | 150 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 96 insertions(+), 54 deletions(-) diff --git a/pathaway.c b/pathaway.c index a8119e9a8..b59a85c4b 100644 --- a/pathaway.c +++ b/pathaway.c @@ -1,6 +1,6 @@ /* Support for PathAway Palm Database, - Copyright (C) 2005 Olaf Klein, o.b.klein@t-online.de + Copyright (C) 2005-2006 Olaf Klein, o.b.klein@t-online.de This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,6 +24,8 @@ The german release 3.0 of PathAway violates the PathAway standards: * N.. .... O.. .... instead of N.. .... E.. .... * date is formatted in DDMMYYYY instead of YYYYMMDD + + Release 4.x store only numeric coordinates and uses a six-number date. */ #include @@ -32,6 +34,7 @@ #include "coldsync/palm.h" #include "coldsync/pdb.h" #include "csv_util.h" +#include "strptime.h" #define MYNAME "pathaway" @@ -45,6 +48,7 @@ static char *fname_in, *fname_out; static short_handle mkshort_handle; static gpsdata_type ppdb_type; static unsigned char german_release = 0; +static char *datefmt; typedef struct ppdb_appdata { @@ -58,15 +62,17 @@ typedef struct ppdb_appdata #define PPDB_APPINFO_SIZE sizeof(struct ppdb_appdata) -static char *dbname = NULL; -static char *deficon = NULL; -static char *snlen_opt = NULL; +static char *opt_dbname = NULL; +static char *opt_deficon = NULL; +static char *opt_snlen = NULL; +static char *opt_date = NULL; static arglist_t ppdb_args[] = { - {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - {"snlen", &snlen_opt, "Length of generated shortnames", "10", ARGTYPE_INT, "1", NULL }, + {"date", &opt_date, "Read/Write date format (i.e. DDMMYYYY)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"dbname", &opt_dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"deficon", &opt_deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"snlen", &opt_snlen, "Length of generated shortnames", "10", ARGTYPE_INT, "1", NULL }, ARG_TERMINATOR }; @@ -226,17 +232,9 @@ char *ppdb_fmt_degrees(char dir, double val) char *str = str_pool_get(32); int deg = fabs(val); double min = 60.0 * (fabs(val) - deg); - int power = 0; - double fx = min; char *tmp; - while (fx > 1.0) - { - fx = fx / 10.0; - power++; - } - snprintf(str, 31, "%c%02d 000", dir, deg); - snprintf(str + 6 - power, 24, "%.8f", min); + snprintf(str, 31, "%c%0*d %.8f", dir, (deg > 99) ? 3 : 2, deg, min); tmp = str + strlen(str) - 1; /* trim trailing nulls */ while ((tmp > str) && (*tmp == '0')) @@ -291,50 +289,81 @@ static int ppdb_decode_tm(char *str, struct tm *tm) { int msec, d1, d2, d3, d4; - time_t tnow; - struct tm now; int year; + char *cx; if (*str == '\0') return 0; /* empty date and time */ if (strchr(str, '.')) /* time in hhmmss.ms */ { - CHECK_INP(8, sscanf(str, "%02d%02d%02d.%d %02d%02d%02d%02d", - &tm->tm_hour, &tm->tm_min, &tm->tm_sec, - &msec, &d1, &d2, &d3, &d4), "decode_tm(1)"); + CHECK_INP(4, sscanf(str, "%02d%02d%02d.%d", + &tm->tm_hour, &tm->tm_min, &tm->tm_sec, &msec), + "decode_tm(1)"); } else { - CHECK_INP(7, sscanf(str, "%02d%02d%02d %02d%02d%02d%02d", - &tm->tm_hour, &tm->tm_min, &tm->tm_sec, - &d1, &d2, &d3, &d4), "decode_tm(2)"); + CHECK_INP(3, sscanf(str, "%02d%02d%02d", + &tm->tm_hour, &tm->tm_min, &tm->tm_sec), + "decode_tm(2)"); } - - tnow = current_time(); - now = *localtime(&tnow); - now.tm_year += 1900; - now.tm_mon++; + cx = strchr(str, ' '); + if (cx == NULL) return 0; /* no date */ - year = (d1 * 100) + d2; + while (*cx == ' ') cx++; + if (*cx == '\0') return 0; /* no date */ - /* the coordinates comes before date and time in - the dataset, so the flag "german_release" is set yet. */ - - /* next code works for most, except for 19. and 20. of month */ - - if ((german_release != 0) || (year < 1980) || (year > now.tm_year)) /* YYYYMMDD or DDMMYYY ????? */ + if (datefmt) { - tm->tm_year = (d3 * 100) + d4; - tm->tm_mon = d2; - tm->tm_mday = d1; + struct tm tm2; + + if (NULL == strptime(cx, datefmt, &tm2)) + { + fatal(MYNAME ": Unable to convert date '%s' using format '%s' (%s)!\n", cx, datefmt, opt_date); + } + + tm->tm_year = tm2.tm_year + 1900; + tm->tm_mon = tm2.tm_mon + 1; + tm->tm_mday = tm2.tm_mday; } else { - tm->tm_year = (d1 * 100) + d2; - tm->tm_mon = d3; - tm->tm_mday = d4; - } + time_t tnow; + struct tm now; + + if (strlen(cx) != 8) + { + printf(MYNAME ": Date from first record is %s.\n", cx); + printf(MYNAME ": Please use option 'date' to specify how this is formatted.\n"); + fatal(MYNAME ": (... -i pathaway,date=DDMMYY ...)\n"); + } + + CHECK_INP(4, sscanf(cx, "%02d%02d%02d%02d", &d1, &d2, &d3, &d4), "decode_tm(3)"); + + tnow = current_time(); + now = *localtime(&tnow); + now.tm_year += 1900; + now.tm_mon++; + + year = (d1 * 100) + d2; + + /* the coordinates comes before date and time in + the dataset, so the flag "german_release" is set yet. */ + /* next code works for most, except for 19. and 20. of month */ + + if ((german_release != 0) || (year < 1980) || (year > now.tm_year)) /* YYYYMMDD or DDMMYYY ????? */ + { + tm->tm_year = (d3 * 100) + d4; + tm->tm_mon = d2; + tm->tm_mday = d1; + } + else + { + tm->tm_year = (d1 * 100) + d2; + tm->tm_mon = d3; + tm->tm_mday = d4; + } + } return 1; } @@ -368,7 +397,7 @@ int ppdb_read_wpt(const struct pdb *pdb_in, const struct pdb_record *pdb_rec, ro { CHECK_INP(1, sscanf(str, "%lf", &altfeet), "altitude"); if (altfeet != -9999) - wpt_tmp->altitude = altfeet / 3.2808; + wpt_tmp->altitude = FEET_TO_METERS(altfeet); } break; case 4: @@ -416,6 +445,10 @@ static void ppdb_rd_init(const char *fname) str_pool_init(); fd_in = xfopen(fname, "rb", MYNAME); + if (opt_date) + datefmt = convert_human_date_format(opt_date); + else + datefmt = NULL; } static void ppdb_rd_deinit(void) @@ -423,6 +456,7 @@ static void ppdb_rd_deinit(void) fclose(fd_in); str_pool_deinit(); xfree(fname_in); + if (datefmt) xfree(datefmt); } static void ppdb_read(void) @@ -446,7 +480,6 @@ static void ppdb_read(void) info = (ppdb_appdata_t *) pdb_in->appinfo; descr = info->vehicleStr; } - switch(pdb_in->type) { case PPDB_MAGIC_TRK: @@ -512,12 +545,20 @@ static void ppdb_wr_init(const char *fname) if (global_opts.synthesize_shortnames != 0) { - len = atoi(snlen_opt); + len = atoi(opt_snlen); setshort_length(mkshort_handle, len); setshort_mustupper(mkshort_handle, 1); setshort_badchars(mkshort_handle, ","); setshort_whitespace_ok(mkshort_handle, 0); } + if (opt_date) + { + char *c = convert_human_date_format(opt_date); + xasprintf(&datefmt, "%s %s", "%H%M%S", c); + xfree(c); + } + else + datefmt = xstrdup("%H%M%S %Y%m%d"); } static void ppdb_wr_deinit(void) @@ -526,6 +567,7 @@ static void ppdb_wr_deinit(void) fclose(fd_out); str_pool_deinit(); xfree(fname_out); + if (datefmt) xfree(datefmt); } /* @@ -564,7 +606,7 @@ static void ppdb_write_wpt(const waypoint *wpt) if (fabs(wpt->altitude) < 9999.0) { tmp = str_pool_get(32); - snprintf(tmp, 32, ppdb_fmt_float(wpt->altitude * 3.2808)); + snprintf(tmp, 32, ppdb_fmt_float(METERS_TO_FEET(wpt->altitude))); buff = ppdb_strcat(buff, tmp, NULL, &len); } buff = ppdb_strcat(buff, ",", NULL, &len); @@ -572,7 +614,7 @@ static void ppdb_write_wpt(const waypoint *wpt) { tmp = str_pool_get(20); tm = *gmtime(&wpt->creation_time); - strftime(tmp, 20, "%H%M%S %Y%m%d", &tm); + strftime(tmp, 20, datefmt, &tm); buff = ppdb_strcat(buff, tmp, NULL, &len); } buff = ppdb_strcat(buff, ",", NULL, &len); @@ -591,7 +633,7 @@ static void ppdb_write_wpt(const waypoint *wpt) buff = ppdb_strcat(buff, tmp, "", &len); buff = ppdb_strcat(buff, ",", NULL, &len); - buff = ppdb_strcat(buff, deficon, "0", &len); + buff = ppdb_strcat(buff, opt_deficon, "0", &len); buff = ppdb_strcat(buff, ",", NULL, &len); tmp = str_pool_getcpy(wpt->description, ""); @@ -637,8 +679,8 @@ static void ppdb_write(void) if (NULL == (pdb_out = new_pdb())) fatal(MYNAME ": new_pdb failed\n"); - if (dbname) - strncpy(pdb_out->name, dbname, PDB_DBNAMELEN); + if (opt_dbname) + strncpy(pdb_out->name, opt_dbname, PDB_DBNAMELEN); pdb_out->name[PDB_DBNAMELEN-1] = 0; pdb_out->attributes = PDB_ATTR_BACKUP; @@ -657,18 +699,18 @@ static void ppdb_write(void) switch(global_opts.objective) /* Only one target is possible */ { case wptdata: - if (dbname == NULL) strncpy(pdb_out->name, "PathAway Waypoints", PDB_DBNAMELEN); + if (opt_dbname == NULL) strncpy(pdb_out->name, "PathAway Waypoints", PDB_DBNAMELEN); pdb_out->type = PPDB_MAGIC_WPT; waypt_disp_all(ppdb_write_wpt); break; case trkdata: - if (dbname == NULL) strncpy(pdb_out->name, "PathAway Track", PDB_DBNAMELEN); + if (opt_dbname == NULL) strncpy(pdb_out->name, "PathAway Track", PDB_DBNAMELEN); pdb_out->type = PPDB_MAGIC_TRK; appinfo->dataBaseSubType = 0; track_disp_all(ppdb_track_header, ppdb_track_trailer, ppdb_write_wpt); break; case rtedata: - if (dbname == NULL) strncpy(pdb_out->name, "PathAway Route", PDB_DBNAMELEN); + if (opt_dbname == NULL) strncpy(pdb_out->name, "PathAway Route", PDB_DBNAMELEN); pdb_out->type = PPDB_MAGIC_TRK; appinfo->dataBaseSubType = 1; route_disp_all(ppdb_track_header, ppdb_track_trailer, ppdb_write_wpt); -- 2.30.2